import {
  ChevronLeftIcon,
  ChevronRightIcon,
  DoubleArrowLeftIcon,
} from "@radix-ui/react-icons";
import { Button } from "@ui/Button";
import { Combobox, Option } from "@ui/Combobox";
import { cn } from "@ui/cn";

interface OffsetPaginationControlsProps {
  currentPage: number;
  totalPages: number;
  onPageChange: (page: number) => void;
  className?: string;
  pageSize?: never;
  onPageSizeChange?: never;
}

interface CursorPaginationControlsProps {
  currentPage: number;
  hasMore: boolean;
  pageSize: number;
  onPageSizeChange: (pageSize: number) => void;
  onPreviousPage: () => void;
  onNextPage: () => void;
  canGoPrevious: boolean;
  className?: string;
  showPageSize?: boolean;
}

interface CursorPaginationControlsPropsWithDiscriminator
  extends CursorPaginationControlsProps {
  isCursorBasedPagination: true;
}

type PaginationControlsProps =
  | OffsetPaginationControlsProps
  | CursorPaginationControlsPropsWithDiscriminator;

const PAGE_SIZE_OPTIONS: Option<number>[] = [
  { label: "5", value: 5 },
  { label: "10", value: 10 },
  { label: "25", value: 25 },
  { label: "50", value: 50 },
  { label: "100", value: 100 },
];

export function PaginationControls(props: PaginationControlsProps) {
  const { isCursorBasedPagination } = props as {
    isCursorBasedPagination?: boolean;
  };
  if (isCursorBasedPagination) {
    const {
      currentPage,
      hasMore,
      pageSize,
      onPageSizeChange,
      onPreviousPage,
      onNextPage,
      canGoPrevious,
      className,
      showPageSize,
    } = props as CursorPaginationControlsPropsWithDiscriminator;
    return (
      <CursorPaginationControls
        currentPage={currentPage}
        hasMore={hasMore}
        pageSize={pageSize}
        onPageSizeChange={onPageSizeChange}
        onPreviousPage={onPreviousPage}
        onNextPage={onNextPage}
        canGoPrevious={canGoPrevious}
        className={className}
        showPageSize={showPageSize}
      />
    );
  }
  const offsetProps = props as OffsetPaginationControlsProps;
  const { currentPage, totalPages, onPageChange, className } = offsetProps;
  return (
    <OffsetPaginationControls
      currentPage={currentPage}
      totalPages={totalPages}
      onPageChange={onPageChange}
      className={className}
    />
  );
}

function OffsetPaginationControls({
  currentPage,
  totalPages,
  onPageChange,
  className = "",
}: OffsetPaginationControlsProps) {
  if (totalPages <= 1) {
    return null;
  }

  return (
    <div className={cn("flex items-center justify-center gap-2", className)}>
      {/* First page button */}
      <Button
        variant="neutral"
        inline
        size="sm"
        icon={<DoubleArrowLeftIcon />}
        onClick={() => onPageChange(1)}
        disabled={currentPage === 1}
        aria-label="Go to first page"
      />

      {/* Previous page button */}
      <Button
        variant="neutral"
        inline
        size="sm"
        icon={<ChevronLeftIcon />}
        onClick={() => onPageChange(Math.max(1, currentPage - 1))}
        disabled={currentPage === 1}
        aria-label="Go to previous page"
      />

      {/* Page indicator */}
      <span className="text-sm text-content-secondary tabular-nums">
        Page {currentPage} of {totalPages}
      </span>

      {/* Next page button */}
      <Button
        variant="neutral"
        inline
        size="sm"
        icon={<ChevronRightIcon />}
        onClick={() => onPageChange(Math.min(totalPages, currentPage + 1))}
        disabled={currentPage === totalPages}
        aria-label="Go to next page"
      />

      {/* Last page button */}
      <Button
        variant="neutral"
        inline
        size="sm"
        icon={<ChevronRightIcon />}
        onClick={() => onPageChange(totalPages)}
        disabled={currentPage === totalPages}
        aria-label="Go to last page"
      />
    </div>
  );
}

function CursorPaginationControls({
  currentPage,
  hasMore,
  pageSize,
  onPageSizeChange,
  onPreviousPage,
  onNextPage,
  canGoPrevious,
  className = "",
  showPageSize = true,
}: CursorPaginationControlsProps) {
  return (
    <div className={cn("flex items-center justify-center gap-2", className)}>
      {/* Page size selector - only show if showPageSize is true */}
      {showPageSize && (
        <div className="flex items-center gap-1">
          <span className="text-sm text-content-secondary tabular-nums">
            Showing{" "}
          </span>
          <Combobox
            label="Page size"
            labelHidden
            options={PAGE_SIZE_OPTIONS}
            selectedOption={pageSize}
            setSelectedOption={(newValue) => {
              if (newValue) {
                onPageSizeChange(newValue);
              }
            }}
            disableSearch
            buttonClasses="w-fit"
            optionsWidth="fit"
          />
          <span className="text-sm text-content-secondary tabular-nums">
            projects per page
          </span>
        </div>
      )}

      {/* Previous page button */}
      <Button
        variant="neutral"
        inline
        size="sm"
        icon={<ChevronLeftIcon />}
        onClick={onPreviousPage}
        disabled={!canGoPrevious}
        aria-label="Go to previous page"
      />

      {/* Page indicator */}
      <span className="text-sm text-content-secondary tabular-nums">
        Page {currentPage.toLocaleString()}
      </span>

      {/* Next page button */}
      <Button
        variant="neutral"
        inline
        size="sm"
        icon={<ChevronRightIcon />}
        onClick={onNextPage}
        disabled={!hasMore}
        aria-label="Go to next page"
      />
    </div>
  );
}
